package com.damai.proxy;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.util.ByteArrayBuffer;

import com.citywithincity.utils.IoUtil;

public class ProxyService implements Filter {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4195867946116543262L;

	public static HttpURLConnection createConnection(String url) throws IOException {
		URL netUrl = new URL(url);
		HttpURLConnection connection = (HttpURLConnection) netUrl.openConnection();

		connection.setConnectTimeout(10000);
		connection.setReadTimeout(10000);
		connection.setUseCaches(false);
		connection.setDoInput(true);

		return connection;
	}

    public static HttpURLConnection postData(HttpURLConnection connection,
                                             byte[] content, Map<String, String> extraHeaders) throws IOException{
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        
        connection.setUseCaches(false);
     //   connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Length", String.valueOf(content.length));
        connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        if(extraHeaders!=null){
            for (Entry<String, String> entry : extraHeaders.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
            if(extraHeaders.containsKey("attach")){	
            	connection.setChunkedStreamingMode(1024);
            	
            }
        }

        OutputStream out = null;
        try {
            // write
            out = new DataOutputStream(connection.getOutputStream());
            out.write(content);
            out.flush();
        } finally {
            IoUtil.close(out);
        }
        return connection;
    }
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}
	private static byte[] read(InputStream stream) throws IOException{
		
		ByteArrayBuffer buffer = new ByteArrayBuffer(0);
		int len = 0;
		byte[] bytes = new byte[1024];
		while ((len = stream.read(bytes)) > 0) {
			buffer.append(bytes, 0, len);
		}
		return buffer.buffer();
	}
	
	private static Map<String, String> getHeaders(HttpServletRequest request){
		Map<String, String> map = new HashMap<String, String>();
		Enumeration<String> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String key = headerNames.nextElement();
			String value = request.getHeader(key);
			map.put(key, value);
		}
		return map;
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		String url = request.getParameter("url");  
		  
		///////////////////////
		HttpURLConnection connection = createConnection(url);
		byte[] readed = read(request.getInputStream());
		
		Map<String, String> headers = getHeaders(request);
		postData(connection,readed , headers);
		
		readed = read(connection.getInputStream());
		response.getOutputStream().write(readed);
		     
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

}
